package cn.lovemmd.model.controller;

import com.alibaba.fastjson2.JSON;
import cn.lovemmd.model.common.Result;
import cn.lovemmd.model.entity.Model;
import cn.lovemmd.model.service.ModelService;
import cn.lovemmd.model.vo.ModelVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 模型控制器 - 用户展示页面后台（只读）
 * 使用FastJson2进行JSON序列化
 * 为了安全考虑，移除了所有增删改功能，只保留查询和统计功能
 * 
 * @author TLS
 * @since 2024-01-01
 */
@RestController
@RequestMapping("/model")
@Api(tags = "模型管理")
@Validated
@RequiredArgsConstructor
@CrossOrigin(origins = "*")
public class ModelController {

    private static final Logger log = LoggerFactory.getLogger(ModelController.class);
    private final ModelService modelService;

    /**
     * 查询模型列表（移除分页，返回所有数据）
     */
    @GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("查询模型列表")
    public ResponseEntity<String> getModelList(
            @ApiParam("搜索关键字") @RequestParam(required = false) String search,
            @ApiParam("职业筛选") @RequestParam(required = false) String occ) {
        
        try {
            List<ModelVO> result = modelService.getModelList(search, occ);
            Result<List<ModelVO>> response = Result.success(result);
            return ResponseEntity.ok(JSON.toJSONString(response));
        } catch (Exception e) {
            log.error("查询模型列表失败", e);
            Result<String> errorResponse = Result.error("查询模型列表失败：" + e.getMessage());
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
    }

    /**
     * 根据ID查询模型详情
     */
    @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("根据ID查询模型详情")
    public ResponseEntity<String> getModelById(
            @ApiParam("模型ID") @PathVariable @NotNull Long id) {
        
        try {
            return getStringResponseEntity(id);
        } catch (Exception e) {
            log.error("查询模型详情失败", e);
            Result<String> errorResponse = Result.error("查询模型详情失败：" + e.getMessage());
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
    }

    private ResponseEntity<String> getStringResponseEntity(@PathVariable @ApiParam("模型ID") @NotNull Long id) {
        ModelVO model = modelService.getModelById(id);
        if (model == null) {
            Result<String> errorResponse = Result.error("模型不存在");
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
        Result<ModelVO> response = Result.success(model);
        return ResponseEntity.ok(JSON.toJSONString(response));
    }



    /**
     * 获取模型统计信息
     */
    @GetMapping(value = "/stats", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("获取模型统计信息")
    public ResponseEntity<String> getModelStats() {
        try {
            Object stats = modelService.getModelStats();
            Result<Object> response = Result.success(stats);
            return ResponseEntity.ok(JSON.toJSONString(response));
        } catch (Exception e) {
            log.error("获取模型统计信息失败", e);
            Result<String> errorResponse = Result.error("获取模型统计信息失败：" + e.getMessage());
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
    }

    /**
     * 获取职业列表
     */
    @GetMapping(value = "/occupations", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("获取职业列表")
    public ResponseEntity<String> getOccupationList() {
        return getStringResponseEntity(modelService, log);
    }

    static ResponseEntity<String> getStringResponseEntity(ModelService modelService, Logger log) {
        try {
            List<Object> occupations = modelService.getOccupationList();
            Result<List<Object>> response = Result.success(occupations);
            return ResponseEntity.ok(JSON.toJSONString(response));
        } catch (Exception e) {
            log.error("获取职业列表失败", e);
            Result<String> errorResponse = Result.error("获取职业列表失败：" + e.getMessage());
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
    }

    /**
     * 根据职业查询模型列表
     */
    @GetMapping(value = "/list/occupation", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("根据职业查询模型列表")
    public ResponseEntity<String> getModelListByOccupation(
            @ApiParam("职业") @RequestParam String occupation) {
        
        try {
            List<Model> models = modelService.selectByOccupation(occupation);
            Result<List<Model>> response = Result.success(models);
            return ResponseEntity.ok(JSON.toJSONString(response));
        } catch (Exception e) {
            log.error("根据职业查询模型列表失败", e);
            Result<String> errorResponse = Result.error("根据职业查询模型列表失败：" + e.getMessage());
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
    }

    /**
     * 根据分类查询模型列表
     */
    @GetMapping(value = "/list/category", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("根据分类查询模型列表")
    public ResponseEntity<String> getModelListByCategory(
            @ApiParam("分类") @RequestParam String category) {
        
        try {
            List<Model> models = modelService.selectByCategory(category);
            Result<List<Model>> response = Result.success(models);
            return ResponseEntity.ok(JSON.toJSONString(response));
        } catch (Exception e) {
            log.error("根据分类查询模型列表失败", e);
            Result<String> errorResponse = Result.error("根据分类查询模型列表失败：" + e.getMessage());
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
    }

    /**
     * 搜索模型
     */
    @GetMapping(value = "/search", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("搜索模型")
    public ResponseEntity<String> searchModels(
            @ApiParam("关键词") @RequestParam String keyword) {
        
        try {
            List<Model> models = modelService.searchByKeyword(keyword);
            Result<List<Model>> response = Result.success(models);
            return ResponseEntity.ok(JSON.toJSONString(response));
        } catch (Exception e) {
            log.error("搜索模型失败", e);
            Result<String> errorResponse = Result.error("搜索模型失败：" + e.getMessage());
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
    }

    /**
     * 获取热门模型
     */
    @GetMapping(value = "/top", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("获取热门模型")
    public ResponseEntity<String> getTopModels(
            @ApiParam("限制数量") @RequestParam(defaultValue = "10") int limit) {
        
        try {
            List<Model> models = modelService.selectTopModels(limit);
            Result<List<Model>> response = Result.success(models);
            return ResponseEntity.ok(JSON.toJSONString(response));
        } catch (Exception e) {
            log.error("获取热门模型失败", e);
            Result<String> errorResponse = Result.error("获取热门模型失败：" + e.getMessage());
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
    }

    /**
     * 生成下载token
     */
    @PostMapping(value = "/token/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("生成下载token")
    public ResponseEntity<String> generateDownloadToken(
            @ApiParam("模型ID") @PathVariable @NotNull Long id,
            @ApiParam("用户名") @RequestParam(required = false) String username,
            HttpServletRequest request) {
        
        try {
            String clientIp = getClientIpAddress(request);
            String token = modelService.generateDownloadToken(id, username, clientIp);
            
            Map<String, Object> result = new HashMap<>();
            result.put("token", token);
            result.put("expiresIn", 300); // 5分钟过期
            
            Result<Map<String, Object>> response = Result.success(result);
            return ResponseEntity.ok(JSON.toJSONString(response));
        } catch (Exception e) {
            log.error("生成下载token失败", e);
            Result<String> errorResponse = Result.error("生成下载token失败：" + e.getMessage());
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
    }

    /**
     * 下载模型（需要token验证）
     */
    @PostMapping(value = "/download/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("下载模型")
    public ResponseEntity<String> downloadModel(
            @ApiParam("模型ID") @PathVariable @NotNull Long id,
            @ApiParam("用户名") @RequestParam(required = false) String username,
            HttpServletRequest request) {
        
        try {
            String clientIp = getClientIpAddress(request);
            
            // 记录下载日志
            modelService.recordDownload(id, username, clientIp, request.getHeader("User-Agent"), request.getHeader("Referer"));
            
            Result<String> response = Result.success("下载记录成功");
            return ResponseEntity.ok(JSON.toJSONString(response));
        } catch (Exception e) {
            log.error("下载模型失败", e);
            Result<String> errorResponse = Result.error("下载模型失败：" + e.getMessage());
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
    }

    /**
     * 访问模型详情
     */
    @GetMapping(value = "/detail/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("访问模型详情")
    public ResponseEntity<String> viewModelDetail(
            @ApiParam("模型ID") @PathVariable @NotNull Long id,
            @ApiParam("用户名") @RequestParam(required = false) String username) {
        
        try {
            // 记录访问日志
            modelService.recordView(id, username, "127.0.0.1", "User-Agent", "Referer");

            return getStringResponseEntity(id);
        } catch (Exception e) {
            log.error("访问模型详情失败", e);
            Result<String> errorResponse = Result.error("访问模型详情失败：" + e.getMessage());
            return ResponseEntity.ok(JSON.toJSONString(errorResponse));
        }
    }

    /**
     * 获取客户端IP地址
     * 
     * @param request HTTP请求
     * @return IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty()) {
            return xForwardedFor.split(",")[0].trim();
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty()) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }
}
